/*
    Android UIML

	Copyright (C) 2010  Bram Goffings (bramgoffings@gmail.com)

	This program is free software; you can redistribute it and/or
	modify it under the terms of the GNU Lesser General Public License
	as published by the Free Software Foundation; either version 2.1
	of	the License, or (at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU Lesser General Public License for more details.

	You should have received a copy of the GNU Lesser General Public License
	along with this program; if not, write to the Free Software
	Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/

package uiml.android.RenderTools;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import uiml.android.elements.Part;
import uiml.android.elements.Property;
import uiml.android.elements.peers.DComponent;
import uiml.android.elements.peers.DMethod;
import uiml.android.elements.peers.DProperty;
import uiml.android.elements.peers.Vocabulary;
import uiml.android.rendering.ReflectionParamTools;

public class RenderUtils {

	public static Object applyProperty(Object obj, Part uiPart, Property property, String method, Vocabulary voc) {
		
		Object value = null;
		
		try {
			// Opvragen van de DProperty, dit is de property die we gaan invoken
			DProperty dproperty = voc.getDProperty(property.getName(), uiPart.getClas(), method);	
			
			// Opvragen method naam
			String methodName = dproperty.getMapsTo();
			
			// Opvragen van de argument types die men kan vinden in dproperty
			Class<?>[] argTypes = ReflectionParamTools.getArgumentTypes(dproperty);
			
			// Opvragen van de argumenten
			// Het aantal argumenten moet overeenkomen met het aantal argTypes 
			// M.a.w. er moet een 1 op 1 match zijn tussen de argumenten en de argument types
			Object[] args = ReflectionParamTools.getArguments(property, argTypes);
	
			// Opvragen van de method die voldoet aan de combinatie methodName en argument types
			Method thisMethod = (obj.getClass()).getMethod(methodName , argTypes);
			
			// Methoden invoken op object met gegeven parameters
			if(method.equals("setMethod"))
				thisMethod.invoke(obj, args);
			else if(method.equals("getMethod"))
				value = thisMethod.invoke(obj, args);
				
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
		
		return value;
	}

	public static Object applyPropertyWithGivenObjectArray(Object propView, Part propPart, Property prop, Object[] args, String method, Vocabulary voc) {
		
		Object value = null;
		
		try {
			// Opvragen van de DProperty, dit is de property die we gaan invoken
			DProperty dproperty = voc.getDProperty(prop.getName(), propPart.getClas(), method);	
			
			// Opvragen method naam
			String methodName = dproperty.getMapsTo();
			
			// Opvragen van de argument types die men kan vinden in dproperty
			Class<?>[] argTypes = ReflectionParamTools.getArgumentTypes(dproperty);
	
			// Opvragen van de method die voldoet aan de combinatie methodName en argument types
			Method thisMethod = ((Object)propView).getClass().getMethod(methodName , argTypes);
			
			// Invoke property
			if(method.equals("setMethod"))
				thisMethod.invoke((Object)propView, args);
			else if(method.equals("getMethod"))
				value = thisMethod.invoke((Object)propView, args);
			
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
		
		return value;
	}
	
	public static Object applyLogicWithGivenObjectArray(String cName, String name, Object[] args, Vocabulary voc) {
		
		Object value = null;
		
		try {
			
			DComponent dcmp = voc.findDComponent(cName);
			
			String className = dcmp.getMapsTo();
			
			// Opvragen van de DProperty, dit is de property die we gaan invoken
			DMethod dmethod = voc.getDMethod(name, cName);	
			
			// Opvragen methodName
			String methodName= dmethod.getMapsTo();
			
			// Opvragen van de argument types die men kan vinden in dproperty
			Class<?>[] argTypes = ReflectionParamTools.getArgumentTypes(dmethod);
	
			// Opvragen van de method die voldoet aan de combinatie methodName en argument types
			Method thisMethod = (Class.forName(className)).getMethod(methodName , argTypes);
			
			// Invoke property
			if(dmethod.getReturnType() != null)
				value = thisMethod.invoke(null, args);
			else
				thisMethod.invoke(null, args);
			
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		
		return value;
		
	}
}
